package edu.gatech.cs2340.bytebankers.game;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import org.ietf.jgss.GSSContext;

import com.sun.org.apache.bcel.internal.generic.I2F;


import edu.gatech.cs2340.bytebankers.model.Journey;
import edu.gatech.cs2340.bytebankers.model.Leader;
import edu.gatech.cs2340.bytebankers.model.RiverCrossing;
import edu.gatech.cs2340.bytebankers.model.Wagon;
import edu.gatech.cs2340.bytebankers.model.profession.Banker;
import edu.gatech.cs2340.bytebankers.model.state.GameState;
import edu.gatech.cs2340.bytebankers.notifications.GameEvents;
import edu.gatech.cs2340.bytebankers.notifications.IListener;
import edu.gatech.cs2340.bytebankers.notifications.Notifier;
import edu.gatech.cs2340.bytebankers.presenter.IJourneyOptionPresenter;
import edu.gatech.cs2340.bytebankers.presenter.IJourneyPresenter;
import edu.gatech.cs2340.bytebankers.presenter.IMapPresenter;
import edu.gatech.cs2340.bytebankers.presenter.IPresenter;
import edu.gatech.cs2340.bytebankers.presenter.IPresenterListener;
import edu.gatech.cs2340.bytebankers.presenter.IRiverPresenter;
import edu.gatech.cs2340.bytebankers.presenter.IStartupPresenter;
import edu.gatech.cs2340.bytebankers.presenter.IStorePresenter;
import edu.gatech.cs2340.bytebankers.presenter.ITownPresenter;
import edu.gatech.cs2340.bytebankers.presenter.JourneyOptionPresenter;
import edu.gatech.cs2340.bytebankers.presenter.JourneyPresenter;
import edu.gatech.cs2340.bytebankers.presenter.MapPresenter;
import edu.gatech.cs2340.bytebankers.presenter.RiverPresenter;
import edu.gatech.cs2340.bytebankers.presenter.StartupPresenter;
import edu.gatech.cs2340.bytebankers.presenter.StorePresenter;
import edu.gatech.cs2340.bytebankers.presenter.TownPresenter;
import edu.gatech.cs2340.bytebankers.view.IStartupView;
import edu.gatech.cs2340.bytebankers.view.IStoreView;
import edu.gatech.cs2340.bytebankers.view.ITownView;
import edu.gatech.cs2340.bytebankers.view.IView;
import edu.gatech.cs2340.bytebankers.view.JourneyOptionView;
import edu.gatech.cs2340.bytebankers.view.JourneyView;
import edu.gatech.cs2340.bytebankers.view.MapView;
import edu.gatech.cs2340.bytebankers.view.RiverView;
import edu.gatech.cs2340.bytebankers.view.StoreView;
import edu.gatech.cs2340.bytebankers.view.TestStoreView;
import edu.gatech.cs2340.bytebankers.view.TownView;
import edu.gatech.cs2340.bytebankers.view.UIStartUpView;

public class GameManager implements IListener {

	static Journey journey;
	
	// Create a frame
	JFrame frame;
	IPresenter presenter;
	IView view;
	GameState gameState;
	
	/**
	 * The main entry point for the game.
	 * @param args
	 */
	public static void main(String[] args)  {
		GameManager gm = new GameManager();
		gm.startGame();
	}
	
	public void startGame()
	{
		gameState = GameState.STARTUP;
		
		
		// Create a frame
		frame = new JFrame("Oregon Trail: Byte Banker Style!");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setBackground(new Color(80, 80, 80));
		frame.setPreferredSize(new Dimension(860, 500));
		  
		journey = new Journey();
	
		
		showStartup();
		/*
		journey = new Journey();
		Wagon wagon = new Wagon();
		Leader leader = new Leader();
		Banker banker = new Banker();
		
		leader.setProfession(banker);
		journey.setLeader(leader);
		journey.setWagon(wagon);
		
		
		
		IStorePresenter presenter = new StorePresenter(journey);
		IStoreView view = new TestStoreView(presenter);
		
		presenter.setView(view);
		showJourney();
		*/
		
		
	}

	private void showStartup() {
		// Create the view/presenter and hook them up
		presenter = new StartupPresenter(journey);
		view = new UIStartUpView((StartupPresenter)presenter);
		((Notifier)presenter).addListener(this);
		((StartupPresenter)presenter).setView((UIStartUpView)view);
		
		// Add the view
		frame.getContentPane().add(view.getMainPanel());
		
		frame.pack();
		frame.setVisible(true);
	}

	
	private void goToStore() {
		journey.setGameState(GameState.SHOPPING);
		// Create the view/presenter and hook them up
		frame.getContentPane().remove(view.getMainPanel());
		presenter = new StorePresenter(journey);
		view = new StoreView((IStorePresenter) presenter);
		((Notifier)presenter).addListener(this);
		((StorePresenter)presenter).setView((StoreView)view);

		// Add the view
		frame.getContentPane().add(view.getMainPanel());
		

		frame.pack();
		
	}
	
	private void showJourney() {
		journey.setGameState(GameState.MOVING);
		// Create the view/presenter and hook them up
		frame.getContentPane().remove(view.getMainPanel());
		presenter = new JourneyPresenter(journey);
		view = new JourneyView((IJourneyPresenter) presenter);
		((Notifier)presenter).addListener(this);
		((JourneyPresenter)presenter).setView((JourneyView)view);

		// Add the view
		frame.getContentPane().add(view.getMainPanel());
		
		frame.pack();
		frame.setVisible(true);
		
		gameState = GameState.MOVING;
	}
	
	private void showOptions() {
		journey.setGameState(GameState.MENU);
		// Create the view/presenter and hook them up
		frame.getContentPane().remove(view.getMainPanel());
		presenter = new JourneyOptionPresenter(journey);
		view = new JourneyOptionView((IJourneyOptionPresenter) presenter);
		((Notifier)presenter).addListener(this);
		((JourneyOptionPresenter)presenter).setView((JourneyOptionView)view);

		// Add the view
		frame.getContentPane().add(view.getMainPanel());
		
		frame.pack();
	}
	
	private void showTown() {
		journey.setGameState(GameState.IN_TOWN);
		
		frame.getContentPane().remove(view.getMainPanel());
		presenter = new TownPresenter(journey);
		view = new TownView((ITownPresenter) presenter);
		((Notifier)presenter).addListener(this);
		((TownPresenter)presenter).setView((TownView)view);

		// Add the view
		frame.getContentPane().add(view.getMainPanel());
		
		frame.pack();

	}
	
	private void showRiver() {
		journey.setGameState(GameState.RIVER_DECISION);
		// Create the view/presenter and hook them up
		frame.getContentPane().remove(view.getMainPanel());
		presenter = new RiverPresenter(journey);
		view = new RiverView((IRiverPresenter) presenter);
		((Notifier)presenter).addListener(this);
		((RiverPresenter)presenter).setView((RiverView)view);

		// Add the view
		frame.getContentPane().add(view.getMainPanel());
		
		frame.pack();
	}
	
	private void showMap() {
		journey.setGameState(GameState.MAP);
		// Create the view/presenter and hook them up
		frame.getContentPane().remove(view.getMainPanel());
		presenter = new MapPresenter(journey);
		view = new MapView((IMapPresenter) presenter);
		((Notifier)presenter).addListener(this);
		((MapPresenter)presenter).setView((MapView)view);

		// Add the view
		frame.getContentPane().add(view.getMainPanel());
		
		frame.pack();
	}

	@Override
	public void actionPerformed(String action) {
		// TODO Auto-generated method stub
		if(action.equals(GameEvents.STARTUP_FINISHED)) {
			if(gameState == GameState.STARTUP) {
				goToStore();	
				return;
			} else {
				throw new RuntimeException("Received STARTUP_FINISHED event when the state was: " + gameState);
			}
		}
		
		if(action.equals(GameEvents.STORE_FINISHED)) {
			if(gameState == GameState.STARTUP) {
				showJourney();	
				return;
			} else if(gameState == GameState.IN_TOWN) {
				showTown();
			} else {
				throw new RuntimeException("Received STORE_FINISHED event when the state was: " + gameState);
			}
		}
		
		if(action.equals(GameEvents.MENU_OPENED)) {
			if(gameState == GameState.MOVING || gameState == GameState.IN_TOWN) {
				showOptions();	
				return;
			} else {
				throw new RuntimeException("Received MENU_OPENED event when the state was: " + gameState);
			}
		}
		
		if(action.equals(GameEvents.MENU_CLOSED)) {
			if(gameState == GameState.MOVING ) {
				showJourney();	
				return;
			} else if(gameState == GameState.IN_TOWN) {
				showTown();
				
			}else {
				throw new RuntimeException("Received MENU_CLOSED event when the state was: " + gameState);
			}
		}
		
		if(action.equals(GameEvents.MAP_OPENED)) {
			if(gameState == GameState.MOVING || gameState == GameState.IN_TOWN) {
				showMap();	
				return;
			} else {
				throw new RuntimeException("Received MAP_OPENED event when the state was: " + gameState);
			}
		}
		
		if(action.equals(GameEvents.MAP_CLOSED)) {
			if(gameState == GameState.MOVING || gameState == GameState.IN_TOWN) {
				showOptions();	
				return;
			} else {
				throw new RuntimeException("Received MAP_CLOSED event when the state was: " + gameState);
			}
		}
		
		if(action.equals(GameEvents.LOCATION_REACHED)) {
			if(journey.getlastLocation() instanceof RiverCrossing) {
				showRiver();
			} else {
				showTown();
			}
		}
		
		if(action.equals(GameEvents.STORE_OPENED)) {
			goToStore();
		}
		
		if(action.equals(GameEvents.TOWN_CONTINUE)) {
			showJourney();
		}
		
		if(action.equals(GameEvents.RIVER_CROSSED)) {
			showJourney();
		}
		
		if(action.equals(GameEvents.GAME_LOADED)) {
			if(journey.getGameState() == GameState.STARTUP) {
				goToStore();	
				return;
			} if (journey.getGameState() == GameState.SHOPPING) {
				goToStore();
			} if (journey.getGameState() == GameState.IN_TOWN) {
				showTown();
			} if (journey.getGameState() == GameState.MOVING) {
				showJourney();
			} if (journey.getGameState() == GameState.RIVER_DECISION) {
				showRiver();
			} if (journey.getGameState() == GameState.MENU) {
				showOptions();
			} if (journey.getGameState() == GameState.MAP) {
				showMap();
			}
		}
	}
	
	public static void setJourney(Journey j){
		journey = j;
	}
	
}
